/*********************************************************************
*                                                                    *
* adisco_3d -- sends data to files                                   *
*                                                                    *
* Parameters:                                                        *
*       inst   -- char with instructions ("O"pen, "P"ut, "C"lose, or "R"ead) *
*       plot   -- struct with ploting data (defined in gen2d.h)      *
*       grid   -- struct with grid data (definied in gen2d.h)        *
*       fields -- pointer to field_array with data                   *
*                                                                    *
* Returns: pointer to file array                                     *
*                                                                    *
* There are several versions according to the ploting program:       *
* adisco_graph    --  for the grapher program                        *
* adisco_maple3   --  for maple V v.3                                *
* adisco_maple5   --  for maple V v.5                                *     
* adisco_mtv      --  for plotmtv                                    * 
* adisco_sv       --  for scivis                                     *
*                                                                    *
*********************************************************************/
#include "first_macro_2d.h"  /* Where global parameters are defined */
#include "structs_2d.h"      /* Where structures are defined */
#include "gen_2d.h"
#ifdef SV
#include "java_ser.h"
#include "java_fser.h"
#endif
#ifdef NETCDF
#include "netcdf.h"
#endif
#ifdef SDF
#include "sdf.h"
#include "sdf_priv.h"
#endif

#define IND_2_PLOT_F(i,j)	( ( (j) * (npp_1) )  +  ((i)) )


/* ----------------------------------------------------------------------------------------------------------------- */

/* --------------------------------------------- adisco_sdf ------------------------------------------------------*/

/* ----------------------------------------------------------------------------------------------------------------- */


#ifdef SDF

struct plot_2d *adisco_sdf_2d(char inst,
			     struct PLOT_PAR *plot_ptr,
			     struct GRID_PAR *grid,
			     struct field_array *fields)
{
  char name[50];         /* used to store part of the plot title. */
  char cnames[50], cnames_extra[50];
  char deltanames[50];
  int ret;
  const int dim = 2, dim_extra;
  int dim_vector[2], dim_vector_extra[2];
  int dsize;
  int csize;
  int level=(*plot_ptr).time_level;
  char tag[10];
  double time, time_extra;
  struct plot_2d plot_extra;

   int grd = (*grid).grid; 
   int n_grid1 = (*grid).n_gridpts_1; 
   int n_grid2 = (*grid).n_gridpts_2;
   int n_gridpts_1 = (*grid).n_gridpts_1;
   int n_gridpts_2 = (*grid).n_gridpts_2;
#ifdef EXCISION
   int exc_grid_1 = (*grid).exc_grid_1;
   int exc_grid_2 = (*grid).exc_grid_2;
#endif

/* number of gridpoints, data from struct plot */


 int npp_1 = (*plot_ptr).grid_plot_pts_1;
 int npp_2 = (*plot_ptr).grid_plot_pts_2;


/* double time = (double)(*fields).a.time; */

/* number of variables, data from struct plot */

const int n_plots = (*plot_ptr).n_plots;

    strcpy(tag, "tag");
    strcpy(cnames, "x|y");
    strcpy(deltanames, "/nx,ny/");

dim_vector[0] = npp_1;
dim_vector[1] = npp_2;

csize = 2*((*plot_ptr).grid_plot_pts_1 * (*plot_ptr).grid_plot_pts_2);
dsize = ((*plot_ptr).grid_plot_pts_1 * (*plot_ptr).grid_plot_pts_2);



 switch (inst) {
 case 'O':{
#ifdef DEBUG_ADISCO
printf("write coordinate values in struct plot (SDF) \n");
#endif

/* form coordinate values for plot */

{
double x_i = (double)(*plot_ptr).initial_x;
double x_f = (double)(*plot_ptr).final_x;
double y_i = (double)(*plot_ptr).initial_y;
double y_f = (double)(*plot_ptr).final_y;
 double swap;

#ifdef OUT_FULL
switch (grd)
{
 case 3:
  swap = x_i - (x_f-x_i);
  x_f = x_f - (x_f-x_i);
  x_i = swap;
  break;
 case 4:
  swap = y_i + (y_f-y_i);
  y_f = y_f + (y_f-y_i);
  y_i = swap;
  break;
 case 5:
  swap = y_i - (y_f-y_i);
  y_f = y_f - (y_f-y_i);
  y_i = swap;
  break;
 default:
  swap = x_i + (x_f-x_i)*grd;
  x_f = x_f + (x_f-x_i)*grd;
  x_i = swap;
  break;
}

(*plot_ptr).coordinate_values = malloc(((*plot_ptr).grid_plot_pts_1 + (*plot_ptr).grid_plot_pts_2) * sizeof(FLOAT));
{register int l;
       for (l = 0; l < npp_1; l++){
(*plot_ptr).coordinate_values[l] = x_i + (double)l/(double)(npp_1-1)*(x_f-x_i);}

       for (l = 0; l < npp_2; l++){
(*plot_ptr).coordinate_values[npp_1+l] = y_i + (double)l/(double)(npp_2-1)*(y_f-y_i);}
}

#endif

#ifdef MID_WRITE

(*plot_ptr).coordinate_values = malloc(2*((*plot_ptr).grid_plot_pts_1 * (*plot_ptr).grid_plot_pts_2) * sizeof(FLOAT));
{register int ind_1, ind_2;
 int N = (*plot_ptr).grid_plot_pts_1 * (*plot_ptr).grid_plot_pts_2;
 FLOAT x, y;
       for (ind_1 = 0; ind_1 < npp_1; ind_1++){
	   for (ind_2 = 0; ind_2 < npp_2; ind_2++){
	       x = x_i + (double)ind_1/(double)(npp_1-1)*(x_f-x_i);
	       y = y_i + (double)ind_2/(double)(npp_2-1)*(y_f-y_i);
	       (*plot_ptr).coordinate_values[IND_2_PLOT_F(ind_1,ind_2)] = y*cos(x);
	       (*plot_ptr).coordinate_values[IND_2_PLOT_F(ind_1,ind_2)+N] = y*sin(x);
	   }
       }
}
#endif

}
 }
   break;

 case 'C':{
#ifdef DEBUG_ADISCO
printf("nothing done \n");
#endif
 }


   break;

 case 'P':{


#ifdef DEBUG_ADISCO
   printf("writing data in sdf files \n");
#endif

   time = (double)(*fields).time;

   {register int field_ind;
   for(field_ind = 0; field_ind < n_plots; field_ind++){

       strcpy(name, "Dump/");

       {register int p_ind2;
       register int p_ind1;
	   for (p_ind2 = 0; p_ind2 < npp_2; p_ind2++){
	       for(p_ind1 = 0 ; p_ind1 < npp_1; p_ind1++){
		   (*plot_ptr).plot_field[IND_2_PLOT_F(p_ind1,p_ind2)] =
		       (double)(*fields).u[(*plot_ptr).pointers[field_ind]][IND_2(p_ind1*(*plot_ptr).factor_1,p_ind2*(*plot_ptr).factor_2)];
	       }
	   }
       }



#ifdef DEBUG_ADISCO
   printf("after creating the vector to write to sdf \n");
fflush(stdout);
#endif

       strcat(name, &(*plot_ptr).window_name[field_ind][0]);
       /* strcat(name, ".nc"); */
#ifdef DEBUG_ADISCO
   printf("after forming the name in sdf \n");
fflush(stdout);
#endif

#ifdef OUT_FULL
	ret=gft_out_full(name,time,&dim_vector[0],cnames,dim,
                              &((*plot_ptr).coordinate_values[0]),(*plot_ptr).plot_field);
#endif
#ifdef MID_WRITE
	ret=mid_write_sdf_stream(name, time, dim, dsize, csize, cnames, 
				 &tag[0], &dim_vector[0], &((*plot_ptr).coordinate_values[0]), (*plot_ptr).plot_field);
#endif
 }
 }
#ifdef DEBUG_ADISCO
   printf("after using grt_out_full in adisco_sdf \n");
fflush(stdout);
#endif

#ifdef DEBUG_ADISCO
printf("finishing writing data in sdf files \n");
#endif
 }
   break;


case 'R':{  // Read data from data file --------------------------------------------------


#ifdef DEBUG_ADISCO
	printf("reading data from sdf files \n");
#endif

   time = (double)(*fields).time;


   {register int field_ind;
   for(field_ind = 0; field_ind < n_plots; field_ind++){


plot_ptr = get_vector_sdf_2d(field_ind, plot_ptr, grid, &fields[0]);

//        strcpy(name, "Dump/");
//        strcat(name, &(*plot_ptr).window_name[field_ind][0]);
//        /* strcat(name, ".nc"); */
// #ifdef DEBUG_ADISCO
// 	printf("after forming the name in sdf \n");
// 	fflush(stdout);
// #endif
// 
//         ret=gft_read_full(name, level, &dim_vector_extra[0], cnames_extra, dim_extra, &time_extra, &(*plot_ptr).coordinate_values[0],&(*plot_ptr).plot_field[0]);
//  
// #ifdef DEBUG_ADISCO
// 	printf("after using grt_read_full in from_disco_sdf \n");
// 	fflush(stdout);
// #endif
// 
// // Checking the data obtained is at the correct time
// 
// 	if(fabs(time-time_extra) > 0.001){
// 		printf("times do not coincide in from_disco time=%f, time_extra=%f, file_name= %s \n",time,time_extra,name);
// 		exit(0);
// 	}
// // Checking the size of the data
// 
// 	if(abs(dim_vector[0] - dim_vector_extra[0]) + abs(dim_vector[0] - dim_vector_extra[0]) > 0.1){
// 		printf("dim data vectors  do not coincide from_disco dim_vector[0] =%d, dim_vector_extra[0]=%d dim_vector[1] =%d, dim_vector_extra[1]=%d \n",dim_vector[0],dim_vector_extra[0],dim_vector[1],dim_vector_extra[1]);
// 		exit(0);
// 	}	
// 
// #ifdef DEBUG_ADISCO
//    printf("after checking time and size\n");
// fflush(stdout);
// #endif
// 
// 
//        {register int p_ind2;
//        register int p_ind1;
// 	   for (p_ind2 = 0; p_ind2 < npp_2; p_ind2++){
// 	       for(p_ind1 = 0 ; p_ind1 < npp_1; p_ind1++){
// 		       (*fields).u[(*plot_ptr).pointers[field_ind]][IND_2(p_ind1*(*plot_ptr).factor_1,p_ind2*(*plot_ptr).factor_2)]=
// 			(FLOAT)(*plot_ptr).plot_field[IND_2_PLOT_F(p_ind1,p_ind2)];
// 	       }
// 	   }
//        }

// changing the name to the data files so that the earlier data is not erased 

      // strcat(&(*plot_ptr).window_name[field_ind][0],"_cont");


}}

#ifdef DEBUG_ADISCO
	printf("finishing reading data in sdf files \n");
#endif
 }
   break;


 default:
     {
	 printf("Unknown command in first argument of adisco\n");
	 exit(0);
	 break;
     }
 }
return(plot_ptr);
 }

#endif



/* ----------------------------------------------------------------------------------------------------------------- */


#ifdef SV

/* ----------------------- adisco_sv ----------------------------------*/

struct plot_3d *adisco_sv_3d(char inst,
			     struct PLOT_PAR *plot_ptr,
			     struct GRID_PAR *gri,
			     struct field_array *fields)
{

  char name[50];         /* used to store part of the plot title. */
  char frame_number[50]; /* used to make several cuts of 3D plots */

/* number of gridpoints, data from struct plot */


 int npp_1 = (*plot_ptr).grid_plot_pts_1;
 int npp_2 = (*plot_ptr).grid_plot_pts_2;

 double time = (double)(*fields).a.time;

/* number of variables, data from struct plot */

const int n_plots = (*plot_ptr).n_plots; 

/* For the moment we make xy plots at z=0 */
/* The x and y axis intervals */

  double bb[] = {(double)(*plot_ptr).initial_x, (double)(*plot_ptr).final_x,
		 (double)(*plot_ptr).initial_y, (double)(*plot_ptr).final_y};

/* printf("npp_1=%d, npp_2=%d \n",npp_1,npp_2); */
/* printf("n_plots=%d\n",n_plots); */
/* printf("initial_x=%f, final_x=%f\n",(*plot_ptr).initial_x,(*plot_ptr).final_x); */
/* printf("initial_y=%f, final_y=%f\n",(*plot_ptr).initial_y,(*plot_ptr).final_y); */

/* exit(0); */



 switch (inst) {
 case 'O':{printf("nothing done\n");
 }
   break;

 case 'C':{printf("nothing done\n"); 
 } 


   break;

 case 'P':
   {register int field_ind;

   for(field_ind = 0; field_ind < n_plots; field_ind++){
	
       strcpy(name, "Dump/");

       /*        printf("time=%f\n",(*fields).a.time); */
       {register int p_ind2;
       register int p_ind1;
       for (p_ind2 = 0; p_ind2 < npp_2; p_ind2++){
	     for(p_ind1 = 0 ; p_ind1 < npp_1; p_ind1++){
/* WARNING     (*plot_ptr).plot_field[field_ind][0][p_ind1][p_ind2] =  */
	       (*plot_ptr).plot_field[IND_2_PLOT(p_ind2,p_ind1)] = 
		       (double)(*fields).u[(*plot_ptr).pointers[field_ind]][IND_(p_ind1*(*plot_ptr).factor_1,p_ind2*(*plot_ptr).factor_2)];
	        }
	     }
	   }
	   strcat(name, &(*plot_ptr).name[field_ind][0]);
	  
	   
	   java_bbser2d_(&name[0], &time, bb, 
			 &npp_1, &npp_2, 
/* WARNING	         &((*plot_ptr).plot_field[field_ind][0][0][0])); */
			 (*plot_ptr).plot_field);
   }
   }

 
   
 
   break;
 default:
     {
	 printf("Unknown command in first argument of adisco\n");
	 exit(0);
	 break;
     }
 }
return(plot_ptr);
 }





/***********************************************************************/



/* ----------------------- adisco_fsv ----------------------------------*/



struct plot_3d *adisco_fsv_2d(char inst, 
			  struct PLOT_PAR *plot_ptr, 
			  struct GRID_PAR *gri, 
			  struct field_array *fields) 
{

    char name[50];           /* used to store part of the plot title. */
    char frame_number[50];   /* used to make several cuts of 3D plots */

/* number of gridpoints, data from struct plot */

 
 int npp_1 = (*plot_ptr).grid_plot_pts_1;
 int npp_2 = (*plot_ptr).grid_plot_pts_2;

 double time = (double)(*fields).a.time;

/* number of variables, data from struct plot */

const int n_plots = (*plot_ptr).n_plots; 

/* For the moment we make xy plots at z=0 */
/* The x and y axis intervals */

  double bb[] = {(double)(*plot_ptr).initial_x, (double)(*plot_ptr).final_x, 
		 (double)(*plot_ptr).initial_y, (double)(*plot_ptr).final_y}; 
  
/* printf("npp_1=%d, npp_2=%d \n",npp_1,npp_2); */
/* printf("n_plots=%d\n",n_plots); */
/* printf("initial_x=%f, final_x=%f\n",(*plot_ptr).initial_x,(*plot_ptr).final_x); */
/* printf("initial_y=%f, final_y=%f\n",(*plot_ptr).initial_y,(*plot_ptr).final_y); */

/* exit(0); */



 switch (inst) {
 case 'O':{printf("nothing done\n");
 }
   break;

 case 'C':{printf("nothing done\n"); 
 } 


   break;

 case 'P':
   {register int field_ind;

   for(field_ind = 0; field_ind < n_plots; field_ind++){

       strcpy(name, "Dump/");

       /*        printf("time=%f\n",(*fields).a.time); */
       {register int p_ind2;
       register int p_ind1;
       for (p_ind2 = 0; p_ind2 < npp_2; p_ind2++){
	 for(p_ind1 = 0 ; p_ind1 < npp_1; p_ind1++){
	 (*plot_ptr).plot_field[IND_2_PLOT(p_ind1,p_ind2)] = 
		       (double)(*fields).u[(*plot_ptr).pointers[field_ind]][IND_2(p_ind1*(*plot_ptr).factor_1,p_ind2*(*plot_ptr).factor_2)];
	       }
	 }
       }

       strcat(name, &(*plot_ptr).window_name[field_ind][0]);


       java_fbbser2d_(&name[0], &time, bb, 
		     &npp_1, &npp_2, 
/* WARNING	      &((*plot_ptr).plot_field[field_ind][0][0][0])); */
		      (*plot_ptr).plot_field);
   }
   }
 
   
 
   break;
 default:
     {
	 printf("Unknown command in first argument of adisco\n");
	 exit(0);
	 break;
     }
 }
return(plot_ptr);
 }




#endif


//--------------------------------------------------------------------------------------------------------------------------------------------------------------------

// This function reads the n's field from data sdf files and put it in the n's field place.

struct plot_2d *get_vector_sdf_2d(int field_ind,
			     struct PLOT_PAR *plot_ptr,
			     struct GRID_PAR *grid,
			     struct field_array *fields)
{
  char name[50];         /* used to store part of the plot title. */
  char cnames[50], cnames_extra[50];
  char deltanames[50];
  int ret;
  const int dim = 2, dim_extra;
  int dim_vector[2], dim_vector_extra[2];
  int dsize;
  int csize;
  int level=(*plot_ptr).time_level;
  char tag[10];
  double time, time_extra;
  struct plot_2d plot_extra;

   int grd = (*grid).grid; 
   int n_grid1 = (*grid).n_gridpts_1; 
   int n_grid2 = (*grid).n_gridpts_2;
   int n_gridpts_1 = (*grid).n_gridpts_1;
   int n_gridpts_2 = (*grid).n_gridpts_2;
#ifdef EXCISION
   int exc_grid_1 = (*grid).exc_grid_1;
   int exc_grid_2 = (*grid).exc_grid_2;
#endif

/* number of gridpoints, data from struct plot */


 int npp_1 = (*plot_ptr).grid_plot_pts_1;
 int npp_2 = (*plot_ptr).grid_plot_pts_2;


/* double time = (double)(*fields).a.time; */

/* number of variables, data from struct plot */

const int n_plots = (*plot_ptr).n_plots;

	if((*plot_ptr).factor_1 != 1){
		printf("In function get_vector_sdf_2d factor different from 1, not implemented yet, exiting\n"); exit(0);
	}	


    strcpy(tag, "tag");
    strcpy(cnames, "x|y");
    strcpy(deltanames, "/nx,ny/");

dim_vector[0] = npp_1;
dim_vector[1] = npp_2;

csize = 2*((*plot_ptr).grid_plot_pts_1 * (*plot_ptr).grid_plot_pts_2);
dsize = ((*plot_ptr).grid_plot_pts_1 * (*plot_ptr).grid_plot_pts_2);


#ifdef DEBUG_ADISCO
	printf("reading data from sdf files \n");
#endif

   time = (double)(*fields).time;


       strcpy(name, "Dump/");
       strcat(name, &(*plot_ptr).window_name[field_ind][0]);

#ifdef DEBUG_ADISCO
	printf("after forming the name in sdf \n");
	fflush(stdout);
#endif

        ret=gft_read_full(name, level, &dim_vector_extra[0], cnames_extra, dim_extra, &time_extra, &(*plot_ptr).coordinate_values[0],&(*plot_ptr).plot_field[0]);
 
#ifdef DEBUG_ADISCO
	printf("after using grt_read_full in from_disco_sdf \n");
	fflush(stdout);
#endif

// Checking the data obtained is at the correct time

	if(fabs(time-time_extra) > 0.001){
		printf("times do not coincide in from_disco time=%f, time_extra=%f, file_name= %s \n",time,time_extra,name);
		exit(0);
	}
// Checking the size of the data

	if(abs(dim_vector[0] - dim_vector_extra[0]) + abs(dim_vector[0] - dim_vector_extra[0]) > 0.1){
		printf("dim data vectors  do not coincide from_disco dim_vector[0] =%d, dim_vector_extra[0]=%d dim_vector[1] =%d, dim_vector_extra[1]=%d \n",dim_vector[0],dim_vector_extra[0],dim_vector[1],dim_vector_extra[1]);
		exit(0);
	}	

#ifdef DEBUG_ADISCO
   printf("after checking time and size\n");
fflush(stdout);
#endif


       {register int p_ind2;
       register int p_ind1;
	   for (p_ind2 = 0; p_ind2 < npp_2; p_ind2++){
	       for(p_ind1 = 0 ; p_ind1 < npp_1; p_ind1++){
		       (*fields).u[(*plot_ptr).pointers[field_ind]][IND_2(p_ind1*(*plot_ptr).factor_1,p_ind2*(*plot_ptr).factor_2)]=
			(FLOAT)(*plot_ptr).plot_field[IND_2_PLOT_F(p_ind1,p_ind2)];
	       }
	   }
       }

return(plot_ptr);}
